#pragma once
#include <cmath>
#include "vector.h"

namespace shermit {

	//////////////////////////////////////////////////////////////////////
    //
    // template class for line without endpoints
    //
    //////////////////////////////////////////////////////////////////////
	template<class VecType>
	class Line {
	public:
		VecType o, d; // point, direction

		GENERAL Line(const VecType &_o, const VecType &_d) : o(_o) {
			d = nv::normalize(_d);
		}

		GENERAL VecType get(typename VecType::value_type t) const {
			return o + d * t;
		}

		GENERAL typename VecType::value_type distance(const VecType &p) const {
			return abs(nv::dot((p - o), VecType(-d.y,d.x)));
		}
	};

	template<class VecType>
	class LineSOA {
	public:
		VecType* o, * d; // point, direction

		GENERAL LineSOA() : o(nullptr), d(nullptr) {}

		GENERAL LineSOA(const LineSOA<VecType>& b) {
			o = b.o;
			d = b.d;
		}

		GENERAL Line<VecType> get(size_t i) const {
			return Line<VecType>(o[i], d[i]);
		}

		GENERAL void set(size_t i, const Line<VecType>& line) {
			o[i] = line.o;
			d[i] = line.d;
		}

		GENERAL VecType at(size_t i, typename VecType::value_type t) const {
			return o[i] + d[i] * t;
		}

		GENERAL typename VecType::value_type distance(size_t i, const VecType& p) const {
			return abs(nv::dot((p - o[i]), VecType(-d[i].y, d[i].x)));
		}
	};
}